﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using System.Threading;
using System.Web;
using System.Net.Sockets;

using System.ComponentModel;

namespace WpfApplication1
{
    class HTTP
    {

        public static Lobby.RequestQuery requestLobbyTrigger;
        public static GameLobby.RequestJoinQuery requestGameTrigger;
        public static GameAdminLobby.RequestAdminQuery requestGameAdminTrigger;
        
        public static bool isAdminGame;

        public static string URL;
        public static string ServerURL;
        public static string port;

        public static bool clientAlreadyStarted = false;

        private static HttpListener listener;

        private static Thread _chatThread;
        public static Thread chatThread
        {
            get { return _chatThread; }
            set { _chatThread = value; }
        }


        public HTTP(String serverUrl)//Lobby.RequestQuery trigger)
        {
            ServerURL = serverUrl;//"http://localhost:8008/";
            URL = "http://localhost:8080/";
            port = URL.Split(':')[2].Split('/')[0];
            Console.WriteLine("LocalPort: "+port);
            //requestLobbyTrigger = trigger;
        }

        public HTTP(Lobby.RequestQuery trigger, string newURL, string serverUrl)
        {
            ServerURL = serverUrl;
            requestLobbyTrigger = trigger;
            URL = "http://" + newURL + "/";
            port = URL.Split(':')[2].Split('/')[0];
            Console.WriteLine("LocalPort: " + port);
            chatThread = new Thread(this.startListening);
            chatThread.Start();
        }

        private void startListening()
        {
            Console.WriteLine("Starting server on url: "+URL);
            while (true)
            {
                HTTP.StartServer();
            }
        }

        public static void StartServer()
        {
            String[] prefixes = new String[1];
            prefixes[0] = "http://*:" + port + "/";
            if (!HttpListener.IsSupported)
            {
                Console.WriteLine("Windows XP SP2 or Server 2003 is required to use the HttpListener class.");
                return;
            }
            // URI prefixes are required, 
            // for example "http://contoso.com:8080/index/".
            if (prefixes == null || prefixes.Length == 0)
                throw new ArgumentException("prefixes");

            // Create a listener.
            //HttpListener listener = 
            listener = new HttpListener();
            // Add the prefixes. 
            foreach (string s in prefixes)
            {
                Console.WriteLine(s);
                listener.Prefixes.Add(s);
            }
            listener.Start();
            Console.WriteLine("Listening...");
            // Note: The GetContext method blocks while waiting for a request. 
            HttpListenerContext context = listener.GetContext();
            HttpListenerRequest request = context.Request;
            Console.WriteLine(request.Url.ToString());
            if (request.Url.ToString() != null)
                decipherURL(request);
            context.Response.Close();
            listener.Stop();
        }

        private static void decipherURL(HttpListenerRequest request)
        {
            string url = request.Url.ToString();
            string data = url.Split('?')[1];
            String[] args = data.Split('&');
            String[] line = args[0].Split('=');
            if (line[1] == "mainlobby")
            {
                requestLobbyTrigger.Invoke(request.Url.ToString().Replace("_~~~_~_~~~_", " "));
            }
            else if (line[1] == "gamelobby")
            {
                if (isAdminGame)
                {
                    requestGameAdminTrigger.Invoke(request.Url.ToString().Replace("_~~~_~_~~~_", " "));
                }
                else
                {
                    requestGameTrigger.Invoke(request.Url.ToString().Replace("_~~~_~_~~~_", " "));
                }
            }
        }

        public static void sendToServer(string URLparameters)
        {
            HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create("http://" + ServerURL + "/");
            URLparameters = URLparameters.Replace(" ", "_~~~_~_~~~_");
            ASCIIEncoding encoding = new ASCIIEncoding();
            Console.WriteLine(URLparameters);
            Console.WriteLine(ServerURL);
            byte[] data = encoding.GetBytes(URLparameters);

            httpWReq.Method = "POST";
            httpWReq.ContentType = "application/x-www-form-urlencoded";
            httpWReq.ContentLength = data.Length;
            Console.WriteLine(ServerURL);
            try
            {
                using (Stream stream = httpWReq.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
            }
            catch { }
        }

        public static string GETfromServer(string getType, string URLparameters)
        {
            HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create("http://" + ServerURL + "/" + getType);
            URLparameters = URLparameters.Replace(" ", "_~~~_~_~~~_");
            ASCIIEncoding encoding = new ASCIIEncoding();
            Console.WriteLine(URLparameters);
            Console.WriteLine(ServerURL);
            byte[] data = encoding.GetBytes(URLparameters);
            httpWReq.Method = "POST";
            httpWReq.ContentType = "application/x-www-form-urlencoded";
            httpWReq.ContentLength = data.Length;
            try
            {
                using (Stream stream = httpWReq.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
                HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
                string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
                return responseString.Split('\r')[0].Replace("_~~~_~_~~~_"," ");
            }
            catch { }
            return "";
        }

        public static string GETfromServer(string URLparameters)
        {
            HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create("http://" + ServerURL + "/");//http://domain.com/page.aspx");
            URLparameters = URLparameters.Replace(" ", "_~~~_~_~~~_");
            ASCIIEncoding encoding = new ASCIIEncoding();
            Console.WriteLine(URLparameters);
            Console.WriteLine(ServerURL);
            byte[] data = encoding.GetBytes(URLparameters);//postData);
            httpWReq.Method = "POST";
            httpWReq.ContentType = "application/x-www-form-urlencoded";
            httpWReq.ContentLength = data.Length;
            try
            {
                using (Stream stream = httpWReq.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
                HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
                string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
                return responseString.Split('\r')[0].Replace("_~~~_~_~~~_"," ");
            }
            catch { }
            return "";
        }

        public static void closeConnection()
        {
            listener.Close();
        }

        public static void setServerURL(string newURL)
        {
            ServerURL = newURL;
        }

        public static string LocalIPAddress()
        {
            IPHostEntry host;
            string localIP = "";
            host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork)
                {
                    localIP = ip.ToString();
                    break;
                }
            }
            return localIP;
        }

        public static void registerGameQuery(GameAdminLobby.RequestAdminQuery trigger)
        {
            requestGameAdminTrigger = trigger;
            isAdminGame = true;
        }

        public static void registerGameQuery(GameLobby.RequestJoinQuery trigger)
        {
            requestGameTrigger = trigger;
        }

        public static String decipherGameType(String type)
        {
            return type == "0" ? "10" : type == "1" ? "20" : type == "2" ? "30" : "30";
        }

    }
}